<!DOCTYPE html>
<html lang="pt">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Uma Referência Visual de Git</title>
  <link rel='stylesheet' type='text/css' href='visual-git-guide.css'>
  <script type="text/javascript" src='visual-git-guide.js'></script>
</head>
<body onload="replace_all_PNGs();">
  <h1 id="top">Uma Referência Visual do Git</h1>

  <div id="language-box">
    <a>Outros Idiomas:</a>
    <ul>
      <li><a href='index-de.html'>Deutsch</a></li>
      <li><a href='index-en.html'>English</a></li>
      <li><a href='index-es.html'>Español</a></li>
      <li><a href='index-fr.html'>Français</a></li>
      <li><a href='index-it.html'>Italiano</a></li>
      <li><a href='index-ja.html'>日本語</a></li>
      <li><a href='index-ko.html'>한국어</a></li>
      <li><a href='index-pl.html'>Polski</a></li>
      <li class="selected">Português</li>
      <li><a href='index-ru.html'>Русский</a></li>
      <li><a href='index-sk.html'>Slovenčina</a></li>
      <li><a href='index-vi.html'>Tiếng Việt</a></li>
      <li><a href='index-zh-cn.html'>简体中文</a></li>
      <li><a href='index-zh-tw.html'>正體中文</a></li>
    </ul>
  </div>

  <p id="link-to-png">Se as figuras não funcionarem, você pode tentar a
  versão <a href="?no-svg">sem SVG</a> desta página.</p>

  <p id="link-to-svg">As figuras SVG foram desabilitadas. <a
      href="index.html">(Reabilitar as figuras SVG)</a></p>

  <p>Esta página fornece uma breve referência visual para os comandos mais
  comuns do git. Uma vez que você saiba um pouco sobre como o git
  funciona, esta página pode consolidar o seu entendimento. Se você está
  interessado em saber como esta página foi criada, veja o meu <a
  href='http://github.com/MarkLodato/visual-git-guide'>repositório no
  GitHub</a>.</p>

  <h2 id="contents">Conteúdo</h2>
  <ol>
    <li><a href="#basic-usage">Uso Básico</a></li>
    <li><a href="#conventions">Convenções</a></li>
    <li><a href="#commands-in-detail">Comandos em Detalhe</a>
      <ol>
        <li><a href="#diff">Diff</a></li>
        <li><a href="#commit">Commit</a></li>
        <li><a href="#checkout">Checkout</a></li>
        <li><a href="#detached">Comitando com um HEAD detachado</a></li>
        <li><a href="#reset">Reset</a></li>
        <li><a href="#merge">Merge</a></li>
        <li><a href="#cherry-pick">Cherry Pick</a></li>
        <li><a href="#rebase">Rebase</a></li>
      </ol>
    </li>
    <li><a href="#technical-notes">Observações Técnicas</a></li>
  </ol>

  <h2 id="basic-usage">Uso Básico</h2>

  <div class="center"><img src='basic-usage.svg.png'></div>

  <p>Os quatro comandos acima copiam arquivos entre o diretório de
  trabalho, o <em>stage</em> (também chamado de índice), e o histórico (na forma de
  <em>commits</em>).</p>

  <ul>

    <li><code>git add <em>arquivos</em></code> copia <em>arquivos</em> (em
    seus estados atuais) para o <em>stage</em>.</li>

    <li><code>git commit</code> salva uma cópia do <em>stage</em> como um
    <em>commit</em>.</li>

    <li><code>git reset -- <em>arquivos</em></code> remove arquivos do
    <em>stage</em>; isto é, copia <em>arquivos</em> do último <em>commit</em> para o <em>stage</em>.
    Use esse comando para "desfazer" um <code>git add
    <em>arquivos</em></code>. Você também pode executar <code>git
    reset</code> para remover todos os arquivos do <em>stage</em>.</li>

    <li><code>git checkout -- <em>arquivos</em></code> copia
    <em>arquivos</em> do <em>stage</em> para o diretório de trabalho.  Use isso
    para descartar alterações locais.</li>

  </ul>

  <p>Você pode usar <code>git reset -p</code>, <code>git checkout
  -p</code>, ou <code>git add -p</code> em vez de (ou além de) especificar
  arquivos para selecionar interativamente partes de arquivos para
  copiar.</p>

  <p>Também é possível passar por cima do <em>stage</em> e copiar (checkout)
  arquivos diretamente do histórico ou de <em>commits</em> sem copiar o aquivo para
  o <em>stage</em>.</p>

  <div class="center"><img src='basic-usage-2.svg.png'></div>

  <ul>

    <li><code>git commit -a </code> é equivalente a executar <tt>git
    add</tt> em todos os arquivos que existiam no último <em>commit</em>, e
    então executar <tt>git commit</tt>.</li>

    <li><code>git commit <em>arquivos</em></code> cria um novo <em>commit</em> com
    o conteúdo do último <em>commit</em>, mais uma cópia de <em>arquivos</em> no
    diretório de trabalho. Além disso, os <em>arquivos</em> são copiados
    para o <em>stage</em>.</li>

    <li><code>git checkout HEAD -- <em>arquivos</em></code> copia os
    <em>arquivos</em> do último <em>commit</em> para ambos o <em>stage</em> e o diretório de
    trabalho.</li>

  </ul>

  <h2 id="conventions">Convenções</h2>

  <p>No restante deste documento, nós vamos usar gráficos no seguinte
  formato.</p>

  <div class="center"><img src='conventions.svg.png'></div>

  <p><em>commits</em> são mostrados em verde com uma identidade de 5 caracteres, e
  eles apontam para os seus pais (parents). Os ramos (branches) são
  mostrados em laranja, e eles apontam para <em>commits</em> específicos. O ramo
  atual é identificado pela referência especial <em>HEAD</em>, que está
  unida àquele ramo. Nessa imagem, os últimos cinco <em>commits</em> são
  mostrados, sendo <em>ed489</em> o mais recente. <em>master</em> (o ramo
  atual) aponta para esse <em>commit</em>, enquanto <em>maint</em> (outro ramo)
  aponta para um ancestral do <em>commit</em> do <em>master</em>.

  <h2 id="commands-in-detail">Comandos em Detalhe</h2>

  <h3 id="diff">Diff</h3>

  <p>Existem várias formas de ver as diferenças entre <em>commits</em>. Abaixo
  estão alguns exemplos comuns. Qualquer desses comandos pode
  opcionalmente receber nomes de arquivos como argumentos que restringem as
  diferenças a esses arquivos.</p>

  <div class="center"><img src='diff.svg.png'></div>

  <h3 id="commit">Commit</h3>

  <p>Quando você comita, o git cria um novo <em>commit</em> usando os arquivos do
  <em>stage</em> e define os pais como o <em>commit</em> atual. Então ele aponta o ramo
  atual para esse novo <em>commit</em>. Na figura abaixo, o ramo atual é o
  <em>master</em>. Antes do comando ser executado, <em>master</em>
  apontava para <em>ed489</em>. Após, um novo <em>commit</em>, <em>f0cec</em>, foi
  criado, com ancestral <em>ed489</em>, e então <em>master</em> foi movido
  para o novo <em>commit</em>.</p>

  <div class="center"><img src='commit-master.svg.png'></div>

  <p>Esse mesmo processo ocorre também quando o ramo atual é um
  ancestral de outro ramo. Abaixo, um <em>commit</em> ocorre no ramo
  <em>maint</em>, o qual era um ancestral de <em>master</em>, resultando
  em <em>1800b</em>. Após, <em>maint</em> não é mais um ancestral de
  <em>master</em>. Para juntar as duas histórias, um <a
  href='#merge'>merge</a> (ou <a href='#rebase'>rebase</a>) será
  necessário.</p>

  <div class="center"><img src='commit-maint.svg.png'></div>

  <p>As vezes um engano ocorre em um <em>commit</em>, mas isso é fácil de corrigir
  com <code>git commit --amend</code>. Quando você usa esse comando, o git
  cria um novo <em>commit</em> com os mesmos pais do <em>commit</em> atual. (O <em>commit</em> antigo
  será descartado se nada fizer referência a ele.)</p>

  <div class="center"><img src='commit-amend.svg.png'></div>

  <p>Um quarto caso é comitar com o <a href="#detached">HEAD
    detachado</a>, como explicado mais tarde.</p>

  <h3 id="checkout">Checkout</h3>

  <p>O comando checkout é usado para copiar arquivos do histórico, ou
  <em>stage</em>, para o diretório de trabalho, e opcionalmente mudar de ramo.</p>

  <p>Quando um nome de arquivo (e/ou <code>-p</code>) é fornecido, o git
  copia esse arquivo do <em>commit</em> para o <em>stage</em> e para o diretório de trabalho.
  Por exemplo, <code>git checkout HEAD~ foo.c</code> copia o arquivo
  <code>foo.c</code> do <em>commit</em> chamado <em>HEAD~</em> (os pais do <em>commit</em>
  atual) para o diretório de trabalho, e também para o <em>stage</em>. (Se nenhum
  <em>commit</em> é fornecido, os arquivos são copiados do <em>stage</em>.) Note que não há
  mudança no ramo.</p>

  <div class="center"><img src='checkout-files.svg.png'></div>

  <p>Quando um nome de arquivo <em>não</em> é fornecido mas a referência é
  um ramo (local), <em>HEAD</em> é movido para aquele ramo (isto é, nós
  passamos para aquele ramo), e então o <em>stage</em> e o diretório de trabalho
  são modificados para coincidir com o conteúdo daquele <em>commit</em>. Qualquer
  arquivo que existe no novo <em>commit</em> (<em>a47c3</em> abaixo) é copiado;
  qualquer arquivo que existe no antigo <em>commit</em> (<em>ed489</em>) mas não no
  novo <em>commit</em> é excluído; e qualquer arquivo que não existe em ambos é
  ignorado.</p>

  <div class="center"><img src='checkout-branch.svg.png'></div>

  <p>Quando um nome de arquivo <em>não</em> é fornecido e a referência
  <em>não</em> é um ramo (local) &mdash; por exemplo, é uma etiqueta
  (tag), um ramo remoto, uma identidade SHA-1, ou algo como
  <em>master~3</em> &mdash; nós obtemos um ramo anônimo, chamado <em>HEAD
    detachado</em>.  Isso é útil para se mover ao longo do histórico. Por
  exemplo, suponha que você queira compilar a versão 1.6.6.1 do git.  Você
  poder executar <code>git checkout v1.6.6.1</code> (que é uma etiqueta,
  não um ramo), compilar, instalar, e então passar de volta para outro
  ramo, por exemplo executado <code>git checkout master</code>. Todavia,
  efetuar um <em>commit</em> funciona um pouco diferente em um HEAD detachado; isso
  é discutido <a href="#detached">abaixo</a>.</p>

  <div class="center"><img src='checkout-detached.svg.png'></div>

  <h3 id="detached">Comitando com um HEAD detachado</h3>

  <p>Quando o <em>HEAD</em> está detachado, comitar funciona da maneira
  usual, exceto que nenhum ramo com nome é modificado. (Você pode pensar
  nisso como um ramo anônimo.)</p>

  <div class="center"><img src='commit-detached.svg.png'></div>

  <p>Uma vez que você fizer um checkout de alguma coisa, por exemplo
  <em>master</em>, o <em>commit</em> (presumivelmente) não recebe outra referência,
  e acaba excluído. Note que após o comando, não há nada fazendo
  referência para <em>2eecb</em>.</p>

  <div class="center"><img src='checkout-after-detached.svg.png'></div>

  <p>Se, por outro lado, você quiser salvar esse estado, você pode criar
  um novo ramo com nome usando <code>git checkout -b
  <em>nome</em></code>.</p>

  <div class="center"><img src='checkout-b-detached.svg.png'></div>

  <h3 id="reset">Reset</h3>

  <p>O comando reset move o ramo atual para uma nova posição, e
  opcionalmente atualiza o <em>stage</em> e o diretório de trabalho. Ele também é
  usado para copiar arquivos do histórico para o <em>stage</em> sem alterar o
  diretório de trabalho.</p>

  <p>Se um <em>commit</em> é realizado sem um nome de arquivo, o ramo atual é
  movido para aquele <em>commit</em>, e então o <em>stage</em> é atualizado para coincidir
  com esse <em>commit</em>. Se <code>--hard</code> é fornecido, o diretório de
  trabalho também é atualizado.  Se <code>--soft</code> é fornecido,
  nem o <em>stage</em> nem o diretório de trabalho são atualizados.</p>

  <div class="center"><img src='reset-commit.svg.png'></div>

  <p>Se um <em>commit</em> não é fornecido, será usado o <em>HEAD</em>.  Nesse
  caso, o ramo não é alterado, mas o <em>stage</em>, e opcionalmente o diretório de
  trabalho se <code>--hard</code> é fornecido, são atualizados com o
  conteúdo do último <em>commit</em>.</p>

  <div class="center"><img src='reset.svg.png'></div>

  <p>Se um nome de arquivo (e/ou <code>-p</code>) é fornecido, então o
  comando funciona similarmente ao comando <a
    href='#checkout'>checkout</a> com um nome de arquivo, exceto que
  apenas o <em>stage</em> (e não o diretório de trabalho) é atualizado. (Você pode
  também especificar o <em>commit</em> a partir do qual copiar os arquivos, em vez
  de <em>HEAD</em>.)</p>

  <div class="center"><img src='reset-files.svg.png'></div>

  <h3 id="merge">Merge</h3>

  <p>Um merge cria um novo <em>commit</em> que incorpora mudanças de outros
  <em>commits</em>. Antes de executar um merge, o <em>stage</em> deve estar igual ao último
  <em>commit</em>. O caso trivial é quando o outro <em>commit</em> é um ancestral do <em>commit</em>
  atual; em tal caso nada ocorre. O próximo caso mais simples é quando o
  <em>commit</em> atual é um ancestral do outro <em>commit</em>. Isso resulta em um merge
  <em>fast-forward</em>. A referência é simplesmente movida, e então é
  efetuado um checkout do novo <em>commit</em>.</p>

  <div class="center"><img src='merge-ff.svg.png'></div>

  <p>Caso contrário, um merge "real" deve ocorrer. Você pode selecionar
  outras estratégias, mas o padrão é efetuar um merge "recursivo", o qual
  basicamente considera o <em>commit</em> atual (<em>ed489</em> abaixo), o outro
  <em>commit</em> (<em>33104</em>), e o ancestral comum a ambos (<em>b325c</em>), e
  efetua um <a href='http://en.wikipedia.org/wiki/Three-way_merge'>merge
  three-way</a>. O resultado é salvo no diretório de trabalho e no
  <em>stage</em>, e então um <em>commit</em> é executado, com um ancestral adicional
  (<em>33104</em>) para o novo <em>commit</em>. </p>

  <div class="center"><img src='merge.svg.png'></div>

  <h3 id="cherry-pick">Cherry Pick</h3>

  <p>O comando cherry-pick "copia" um <em>commit</em>, criando um novo <em>commit</em> no ramo
  atual com a mesma mensagem e modificações de outro <em>commit</em>.</p>

  <div class="center"><img src='cherry-pick.svg.png'></div>

  <h3 id="rebase">Rebase</h3>

  <p>Um rebase é uma alternativa a um <a href='#merge'>merge</a> para
  combinar vários ramos. Enquanto um merge cria um único <em>commit</em> com dois
  pais, gerando um histórico não-linear, um rebase efetua os <em>commits</em> do
  ramo atual em outro ramo, gerando um histórico linear. Em essência, isso
  é uma forma automática de executar vários <a
    href='#cherry-pick'>cherry-pick</a>s em sequência.</p>

  <div class="center"><img src='rebase.svg.png'></div>

  <p>O comando acima considera todos os <em>commits</em> que existem em
  <em>topic</em> mas não em <em>master</em> (a saber <em>169a6</em> e
  <em>2c33a</em>), executa esses <em>commits</em> em <em>master</em>, e então move
  o HEAD para o novo <em>commit</em>. Note que os <em>commits</em> antigos serão descartados
  se nada mais fizer referência a eles.</p>

  <p>Para limitar quanto se quer ir para trás, use a opção
  <code>--onto</code>. O seguinte comando executa em <em>master</em> os
  <em>commits</em> mais recentes do ramo atual desde <em>169a6</em>
  (exclusivamente), a saber <em>2c33a</em>.</p>

  <div class="center"><img src='rebase-onto.svg.png'></div>

  <p>Existe também o comando <code>git rebase --interactive</code>, o qual
  permite fazer coisas mais complicadas do que simplesmente executar
  novamente <em>commits</em>, a saber, remover, reordenar, modificar, e "amassar"
  <em>commits</em> (squashing). Não existe uma figura clara para representar isso;
  veja <a 
    href='http://www.kernel.org/pub/software/scm/git/docs/git-rebase.html#_interactive_mode'>git-rebase(1)</a>
  para mais detalhes.</p>

  <h2 id="technical-notes">Observações técnicas</h2>

  <p>O conteúdo dos arquivos não é na verdade armazenado no index
  (<em>.git/index</em>) ou em objetos <em>commit</em>.  Em vez disso, cada arquivo
  é armazenado na base-de-dados de objetos (<em>.git/objects</em>) como um
  <em>blob</em>, identificado pelo seu código hash SHA-1. O arquivo index
  lista os nomes de arquivos juntamente com o identificador do blob
  associado, bem como alguns outros dados. Para <em>commits</em>, existe um tipo de
  dado adicional, uma <em>árvore</em>, também identificado pelo seu código
  hash. Árvores correspondem aos diretórios no diretório de trabalho, e
  contém uma lista das árvores e blobs correspondentes a cada nome de
  arquivo naquele diretório. Cada <em>commit</em> armazena o identificador da sua
  árvore, que por sua vez contém todos os blobs e outras árvores
  associadas àquele <em>commit</em>. </p>

  <p>Se você realiza um <em>commit</em> usando um HEAD detachado, o último <em>commit</em> é
  na verdade referenciado por algo: o reflog para o HEAD. Todavia, esse
  possui data de validade, logo em algum momento posterior o <em>commit</em>
  será finalmente excluído, de forma similar aos <em>commits</em> excluídos com
  <code>git commit --amend</code> ou <code>git rebase</code>.</p>

  <hr>

  <p>Copyright &copy; 2010,
    <a href='mailto:lodatom@gmail.com'>Mark Lodato</a>.
  Portuguese translation &copy; 2014,
    <a href='mailto:goliveira5d@gmail.com'>Gustavo de Oliveira</a>
  </p>

  <p><a rel="license"
    href="https://creativecommons.org/licenses/by-nc-sa/3.0/us/deed.pt_BR">
    <img alt="" src="https://i.creativecommons.org/l/by-nc-sa/3.0/us/80x15.png"></a>
  Este trabalho está sob a licença <a rel="license"
    href="https://creativecommons.org/licenses/by-nc-sa/3.0/us/deed.pt_BR">
    Atribuição-NãoComercial-CompartilhaIgual 3.0 Estados Unidos</a>.</p>

  <p><a href='translate-en.html'>Gostaria de traduzir para outro idioma?</a></p>

</body>
</html>
